<template>
	<view class="game-box" @touchstart.prevent="touchstartFn" @touchend.prevent="touchendFn">
		<view class="line-box" ref="lineBox" v-for="items in arr" :key="items">
			<view class="num-block" v-for="item in items" :key="item" :style="item!==0?'':'opacity:0'">
				{{item}}
			</view>
		</view>
	</view>
</template>

<script setup>
	import {
		defineComponent,
		onMounted,
		ref,
		watchEffect,
	} from 'vue';
	import utils from '../../../utils';

	const props = defineProps({
		col: Number,
		initArr: {
			type: Array,
			default: []
		}
	})
	let arr = ref([])
	let oldArr = []
	let level = ref(0)
	let x = ref(0)
	let y = ref(0)
	let lineBox = ref(null)

	onMounted(() => {
		init()
	})

	const emit = defineEmits(["getSum"])

	watchEffect(() => {
		let sum = 0
		arr.value.forEach(items => {
			items.forEach(item => {
				sum += item
			})
		})
		if (sum >= 64) {
			level.value = 1
		} else if (sum >= 256) {
			level.value = 2
		}
		emit("getSum", sum)
	})

	const addRandomNumber = (Arr, level, type = "bottom") => {
		//level  难度等级
		let numTemp = (Math.round(Math.random()) + level) * 2
		if (numTemp == 0) {
			numTemp = 2
		}
		let rowTemp = Math.round(Math.random() * (props.col - 1))
		let isDone = false
		if (type === "top" || type === "left") {
			for (var i = 0; i < Arr.length; i++) {
				if (Arr[i][rowTemp] === 0 && !isDone) {
					Arr[i][rowTemp] = numTemp
					isDone = true
				}
				break;
			}
		} else if (type === "bottom" || type === "right") {
			for (var i = Arr.length - 1; i >= 0; i--) {
				if (Arr[i][rowTemp] === 0 && !isDone) {
					Arr[i][rowTemp] = numTemp
					isDone = true
				}
			}
		}
		if (!isDone) {
			addRandomNumber(Arr, level, type)
		}
	}
	const init = () => {
		if (props.initArr.length != 0) {
			arr.value = props.initArr
		} else {
			//随机生成一个数组
			for (var i = 0; i < props.col; i++) {
				let arrTemp = []
				for (var j = 0; j < props.col; j++) {
					arrTemp.push(0)
				}
				arr.value.push(arrTemp)
			}
			let numTemp = (Math.round(Math.random()) + level.value) * 2
			let colTemp = Math.round(Math.random() * (props.col - 1))
			if (numTemp === 0) {
				numTemp = 2
			}
			arr.value[props.col - 1][colTemp] = numTemp
		}
	}

	const touchstartFn = (e) => {
		e.preventDefault()
		let event = e.touches && e.touches[0] ? e.touches[0] : e.changedTouches[0]
		x.value = event.clientX
		y.value = event.clientY
	}
	const touchendFn = (e) => {
		e.preventDefault()
		let event = e.touches && e.touches[0] ? e.touches[0] : e.changedTouches[0]
		let tempX = event.clientX - x.value
		let tempY = event.clientY - y.value
		//修改x,y测试是否生效
		let type = ""
		if (Math.abs(tempX) > Math.abs(tempY)) {
			//判断x是向左还是向右
			if ((tempX) > 0) {
				//右
				type = "right"
			} else if ((tempX) < 0) {
				//左
				type = "left"
			}
		} else {
			//判断y是向上还是向下
			if ((tempY) > 0) {
				//下
				type = "bottom"
			} else if ((tempY) < 0) {
				//上
				type = "top"
			}
		}
		toGo(type, props.col)
		if (JSON.stringify(oldArr) != JSON.stringify(arr.value)) {
			addRandomNumber(arr.value, level.value, type)
		}
	}
	const toGo = (type, col) => {
		oldArr = arr.value
		let rowArr = JSON.parse(JSON.stringify(arr.value));
		let colArr = rowToCol(col)
		let cols = lineBox.value
		switch (type) {
			case "left":
				removeZero(rowArr)
				leftOrRight(rowArr, type, col, cols);
				break;
			case "right":
				removeZero(rowArr)
				leftOrRight(rowArr, type, col, cols);
				break;
			case "top":
				removeZero(colArr)
				upOrDown(colArr, type, col)
				break;
			case "bottom":
				removeZero(colArr)
				upOrDown(colArr, type, col)
				break;
		}
	}
	const leftOrRight = (rowArr, type, col, cols) => {
		if (type === "right") {
			if (rowArr && rowArr.length != 0) {
				for (let i = 0; i < cols.length; i++) {
					const element = cols[i];
					element.classList = ["to-right line-box"]
				}
				rowArr.map(items => {
					if (items && items.length != 0) {
						for (var i = items.length - 1; i > 0; i--) {
							if (items[i] !== 0 && items[i] == items[i - 1]) {
								items[i] += items[i - 1]
								items.splice(i - 1, 1)
							}
						}
					}
				})
			}
		} else if (type === "left") {
			if (rowArr && rowArr.length != 0) {
				for (let i = 0; i < cols.length; i++) {
					const element = cols[i];
					element.classList = ["to-left line-box"]
				}
				rowArr.map(items => {
					if (items && items.length != 0) {
						for (var i = 0; i < items.length - 1; i++) {
							if (items[i] !== 0 && items[i] == items[i + 1]) {
								items[i] += items[i + 1]
								items.splice(i + 1, 1)
							}
						}
					}
				})
			}
		}
		addZero(type, rowArr, col)
		arr.value = rowArr
	}
	const upOrDown = (colArr, type, col) => {
		if (type === "top") {
			colArr.forEach(items => {
				for (var i = 0; i < items.length - 1; i++) {
					if (items[i] !== 0 && items[i] == items[i + 1]) {
						items[i] += items[i + 1]
						items.splice(i + 1, 1)
					}
				}
			})
			//处理colArr 为横向数据   先补0
		} else if (type === "bottom") {
			colArr.forEach(items => {
				for (var i = items.length - 1; i > 0; i--) {
					if (items[i] !== 0 && items[i] == items[i - 1]) {
						items[i] += items[i - 1]
						items.splice(i - 1, 1)
					}
				}
			})
			//处理colArr 为横向数据   先补0
		}
		addZero(type, colArr, col)
		// 处理列数组为行数组
		arr.value = colToRow(colArr, col, type)
	}
	const colToRow = (colArr, col, type) => {
		let tempArr = []
		for (let i = col - 1; i >= 0; i--) {
			let temp = []
			colArr.forEach(items => {
				// if (items[i]) {
				temp.push(items[i])
				// }
			})
			tempArr.push(temp)
		}
		return tempArr.reverse()
	}
	const rowToCol = (col) => {
		let colArr = []
		for (let i = 0; i < col; i++) {
			let temp = []
			arr.value.forEach(items => {
				temp.push(items[i])
			})
			colArr.push(temp)
		}
		return colArr
	}
	const removeZero = (arr) => {
		arr.forEach(items => {
			if (items.indexOf(0) != -1) {
				items.splice(items.indexOf(0), 1)
			}
		})
		arr.forEach(item => {
			if (item.indexOf(0) != -1) {
				removeZero(arr)
			}
		})
		return arr
	}
	const addZero = (type, tempArr, col) => {
		if (type === "top") {
			tempArr.forEach(item => {
				if (item.length < col) {
					let temp = col - item.length
					for (let i = 0; i < temp; i++) {
						item.push(0)
					}
				}
			})
		} else if (type === "bottom") {
			tempArr.forEach(item => {
				if (item.length < col) {
					let temp = col - item.length
					for (let i = 0; i < temp; i++) {
						item.unshift(0)
					}
				}
			})
		} else if (type === "left") {
			tempArr.forEach(item => {
				if (item.length < col) {
					let temp = col - item.length
					for (let i = 0; i < temp; i++) {
						item.push(0)
					}
				}
			})
		} else if (type === "right") {
			tempArr.forEach(item => {
				if (item.length < col) {
					let temp = col - item.length
					for (let i = 0; i < temp; i++) {
						item.unshift(0)
					}
				}
			})
		}
	}
	const backspace = () => {
		if (JSON.stringify(oldArr) != JSON.stringify(arr.value)) {
			if (oldArr && oldArr.length != 0) {
				arr.value = oldArr
				return true
			} else {
				return false
			}
		} else {
			return false
		}
	}

	const saveData = () => {
		let id = uni.getStorageSync("uni-id-pages-userInfo")._id
		let userName = uni.getStorageSync("uni-id-pages-userInfo").username
		utils.requestCloudDB("get", {
			collection: "GAME_2048_TAB",
			whereParam: {
				userId: id
			},
			limitParam: 1
		}, (res) => {
			let dataParam = {
				"valueArr": arr.value,
				"userId": id,
				"userName": userName
			}
			if (res.data && res.data.length != 0) {
				//存在数据  用update
				updateData(dataParam)
			} else {
				// 不存在  用add
				addData(dataParam)
			}
		})
	}
	const updateData = (dataParam) => {
		let id = uni.getStorageSync("uni-id-pages-userInfo")._id
		utils.requestCloudDB("update", {
			collection: "GAME_2048_TAB",
			whereParam: {
				userId: id
			},
			data: {
				"valueArr": arr.value
			}
		}, (res) => {
			console.log("更新成功")
		})
	}

	const addData = (dataParam) => {
		utils.requestCloudDB("add", {
			collection: "GAME_2048_TAB",
			data: dataParam
		}, (res) => {
			console.log("新增成功")
		})
	}


	defineExpose({
		backspace,
		saveData
	})
</script>

<style scope>
	.game-box {
		height: 90vw;
		width: 90vw;
		border: 1rpx solid #ccc;
		box-sizing: border-box;
	}

	.line-box {
		display: flex;
	}

	.num-block {
		height: calc(18vw - 3rpx);
		width: calc(18vw - 3rpx);
		box-sizing: border-box;
		display: flex;
		justify-content: center;
		align-items: center;
		margin: 1rpx;
		background-color: #f7efe4;
		font-size: 50rpx;
		font-weight: bolder;
		color: #b6b6b6;
	}

	@keyframes leftToRight {
		0% {
			justify-content: flex-start;
		}

		50% {
			justify-content: center;
		}

		100% {
			justify-content: flex-end;
		}
	}

	.to-right {
		animation-name: leftToRight;
		animation-duration: 0.1s;
		animation-fill-mode: forwards;
	}

	@keyframes leftToLeft {

		0% {
			justify-content: flex-end;
		}

		50% {
			justify-content: center;
		}

		100% {
			justify-content: flex-start;
		}
	}

	.to-left {
		animation-name: leftToLeft;
		animation-duration: 0.1s;
		animation-fill-mode: forwards;
	}
</style>